﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;


public class PostValue
{
    public string type;
    public string charset;
    public string key;
    //public string value;
    public string filename;
    public byte[] data;
}
public class DecodePost
{

    private static string GetData(string key, string[] contexts)
    {
        for (int i = 0; i < contexts.Length; i++)
        {
            string[] strs = contexts[i].Split('=');
            if (strs.Length < 2)
                continue;
            if (strs[0].Trim() == key)
                return strs[1].Trim().Replace("\"", "");
        }
        return null;
    }


    public static List<PostValue> GetPostValue(HttpListenerContext request)
    {
        List<PostValue> valueList = new List<PostValue>();

        if (request.Request.ContentType.Length > 20 && string.Compare(request.Request.ContentType.Substring(0, 20), "multipart/form-data;", true) == 0)
        {
            string[] HttpListenerPostValue = request.Request.ContentType.Split(';').Skip(1).ToArray();
            string boundary = string.Join(";", HttpListenerPostValue).Replace("boundary=", "").Replace("\"", "").Trim();
            boundary = "--" + boundary;
            ////开始标识
            //byte[] ChunkBoundary = Encoding.UTF8.GetBytes("--" + boundary + "\r\n");
            ////结束表示
            //byte[] EndBoundary = Encoding.UTF8.GetBytes("--" + boundary + "--\r\n");
            Stream sourceStream = request.Request.InputStream;
            var resultStream = new MemoryStream();
            byte[] buffer = new byte[1024];
            int len = 0;
            while (true)
            {
                if ((len = sourceStream.Read(buffer, 0, buffer.Length)) != buffer.Length)
                {
                    resultStream.Write(buffer, 0, len);
                    break;
                }
                resultStream.Write(buffer, 0, len);
            }
            buffer = new byte[resultStream.Length];
            resultStream.Position = 0;
            resultStream.Read(buffer, 0, buffer.Length);

            string allstr = Encoding.ASCII.GetString(buffer);
            string[] validString = allstr.Split(new string[] { boundary }, StringSplitOptions.None);

            int index = 0;
            for (int i = 0; i < validString.Length; i++)
            {
                if (validString[i] == "")
                {
                    index += boundary.Length;
                    continue;
                }
                else if (validString[i] == "\r\n")
                {
                    index += boundary.Length + 2;
                    continue;
                }
                else if (validString[i] == "--\r\n")
                {
                    index += boundary.Length;
                    continue;
                }
                int dataIndex = validString[i].IndexOf("\r\n\r\n") + index + 4;
                PostValue data = new PostValue();
                valueList.Add(data);
                string[] items = validString[i].Split(new string[] { "\r\n" }, StringSplitOptions.None);
                int itemIndex = 0;
                for (int j = 0; j < items.Length; j++)
                {
                    string cmd = items[j];
                    if (cmd == "")
                    {
                        itemIndex += 2;
                        continue;
                    }

                    if (cmd.Length >= 19 && cmd.Substring(0, 19).ToLower().StartsWith("content-disposition"))
                    {
                        int bufferIndex = index + itemIndex;
                        string tempStr = Encoding.UTF8.GetString(buffer, bufferIndex, dataIndex - bufferIndex);
                        tempStr = tempStr.Substring(0, tempStr.IndexOf("\r\n"));
                        string[] segments = tempStr.Split(';');
                        data.key = data.key = GetData("name", segments);
                        data.filename = GetData("filename", segments);
                    }
                    else if (cmd.Length >= 12 && cmd.Substring(0, 12).ToLower().StartsWith("content-type"))
                    {
                        string[] segments = cmd.Split(';');
                        data.type = segments[0].Split(':')[1].Trim();
                        data.charset = GetData("charset", segments);
                    }
                    else
                    {
                        int dataLength = 0;
                        while (true)
                        {
                            dataLength += items[j].Length;
                            if (j == items.Length - 2)
                            {
                                data.data = new byte[dataLength];
                                Buffer.BlockCopy(buffer, dataIndex, data.data, 0, dataLength);
                                break;
                            }
                            dataLength += 2;
                            j++;
                        }
                    }
                    itemIndex += items[j].Length + 2;
                }

                index += validString[i].Length + boundary.Length;
            }
            return valueList;
        }
        //else if (request.Request.ContentType.Length >= 33 && string.Compare(request.Request.ContentType.Substring(0, 33), "application/x-www-form-urlencoded", true) == 0)
        //{
        //    Stream SourceStream = request.Request.InputStream;
        //    using (StreamReader reader = new StreamReader(SourceStream))
        //    {
        //        string allStr = reader.ReadToEnd();
        //        string[] allClip = allStr.Split('&');
        //        for (int i = 0; i < allClip.Length; i++)
        //        {
        //            PostValue data = new PostValue();
        //            valueList.Add(data);
        //            string[] onemsg = allClip[i].Split('=');
        //            data.key = onemsg[0];
        //            data.value = onemsg[1];
        //        }

        //    }
        //    Console.WriteLine((GetTimestamp() - t0) + "=============================================================");
        //    return valueList;
        //}
        return null;
    }
}

